import { appRef } from "@/models/app.ref";
import { BaseServices } from "./base.services";
import { Message } from "@arco-design/web-vue";
import { blobToFile } from "@/utils/common.methods";
import { AssetInfo } from "@/models/asset";
import { hope } from "@/tools/hope/@types/hope";

export class DrawService extends BaseServices {
  private static _ins: DrawService = new DrawService();
  public static get ins(): DrawService {
    return this._ins ? this._ins : (this._ins = new DrawService());
  }

  public getModels(): Promise<void> {
    const url = "https://jump.zaiwen.top/admin/img_gen/config/get";
    return new Promise<void>((resolve) => {
      if (appRef.aidraw?.models?.length) {
        resolve();
      } else {
        this.get(url)
          .then(async (res: any) => {
            appRef.aidraw.setModels(res.presets);
            resolve();
          })
          .catch((err) => {
            resolve(err);
          });
      }
    });
  }

  /**
   * AI 绘画
   * 根据提示词生成图片
   * @param prompt
   * @param negative_prompt
   * @param model_name
   * @returns
   */
  public generate(prompt: string, negative_prompt: string = "", model_name: string): Promise<string> {
    if (!model_name) model_name = appRef.aidraw?.models[0]?.name;
    const url = "https://cwjiaoyu.cn/img_generate";
    const data = { prompt, negative_prompt, model_name, key: appRef.user.data?.openai_key };
    return new Promise<string>((resolve, reject) => {
      this.request(url, data)
        .then(async (res: { task_id: string }) => {
          const task_id = res.task_id;
          appRef.aidraw.updateImage(task_id, {} as AssetInfo, prompt, negative_prompt, model_name);
          resolve(task_id);
        })
        .catch((err) => {
          Message.error("图片生成错误，请再试一次吧");
          reject(err);
        });
    });
  }

  /**
   * 图生图 V2
   * @param data
   * @param model_name
   * @returns
   */
  public generateV2(value: { prompt: string; negative_prompt: string; width: number; height: number; ratio: string; step: number; picture_weight: number; original: AssetInfo; model_name: string }): Promise<string> {
    if (!value?.model_name) value.model_name = appRef.aidraw?.models[0]?.name;
    const { prompt, negative_prompt, width, height, ratio, step, picture_weight, original, model_name } = value;
    const url = "https://www.cwjiaoyu.cn/img_generate2";
    const data = { prompt, negative_prompt, step, width, height, picture_weight, ratio, original_image: original.id, mask_image: "", model_name, key: appRef.user.data?.openai_key };
    return new Promise<string>((resolve, reject) => {
      this.request(url, data, "POST")
        .then(async (res: { task_id: string }) => {
          const task_id = res.task_id;
          appRef.aidraw.updateImage(task_id, {} as AssetInfo, prompt, negative_prompt, model_name, picture_weight, ratio, original, width, height, step);
          resolve(task_id);
        })
        .catch((err) => {
          Message.error("图片生成错误，请再试一次吧");
          reject(err);
        });
    });
  }

  public checkTaskStatus(task_id: string): Promise<AssetInfo> {
    const url = `https://www.cwjiaoyu.cn/img_generate_task/${task_id}`;
    return new Promise<AssetInfo>((resolve, reject) => {
      fetch(url)
        .then(async (res: Response) => {
          console.log(res);
          if (res.status == 200) {
            const blob = await res.blob();
            hope.upload({
              files: [blobToFile(blob, task_id + ".png")],
              success: (res) => {
                resolve(res[0]);
              },
            });
          } else {
            const statusData = await res.json();
            if (statusData.status === "进行中") {
              setTimeout(() => resolve(this.checkTaskStatus(task_id)), 1000);
            } else {
              reject();
              Message.error("图片获取错误");
              console.error("错误: ", statusData.error);
              throw new Error("图片生成错误");
            }
          }
        })
        .catch((error) => {
          reject();
          Message.error("图片获取错误");
          console.error("错误: ", error);
          throw new Error("图片生成错误");
        });
    });
  }
}

export const drawService: DrawService = DrawService.ins;
